package com.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.reggie.common.R;
import com.reggie.dto.DishDto;
import com.reggie.entity.category;
import com.reggie.entity.dish;
import com.reggie.entity.dishFlavor;
import com.reggie.entity.setMealDish;
import com.reggie.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("/dish")
@Transactional
public class dishController {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private dishService dishService;

    @Autowired
    private dishFlavorService dishFlavorService;

    @Autowired
    private categoryService categoryService;
    //实现对套餐菜品的控制
    @Autowired
    private setMealDishService setMealDishService;

    /**
     * @param dish
     * @return com.reggie.common.R<java.lang.String>
     * @description: 使用Dto前端转送给后端的数据转换格式, 包含了dish和flavor地属性
     * @author 86187
     * @date: 2022/11/18 17:18
     */

    @PostMapping()
    public R<String> saveDish(@RequestBody DishDto dish) {
        System.out.println(dish);
        dish.setSort(0);
        dish.setPrice(Double.valueOf(dish.getPrice() / 100));
        dishService.saveDto(dish);
        //清除相应菜品的缓存
        redisTemplate.delete("dish:" + dish.getCategoryId());
        return R.success("保存成功!");
    }

    /**
     * @param page
     * @param pageSize
     * @param name
     * @param session
     * @return com.reggie.common.R<com.baomidou.mybatisplus.extension.plugins.pagination.Page>
     * @description: 获取菜品列表
     * @author 86187
     * @date: 2022/11/18 15:25
     */

    @GetMapping("/page")
    public R<Page> selectDishListByCondition(int page, int pageSize, String name, HttpSession session) {
        return dishService.SelectDishForCategoryName(page, pageSize, name, session);
    }

    /**
     * @param ids
     * @return com.reggie.common.R<java.lang.String>
     * @description: 将菜品和对应的口味设置为删除状态, 同时将其删除
     * @author 86187
     * @date: 2022/11/18 15:25
     */

    @DeleteMapping()
    public R<String> deleteByCondition(@RequestParam("ids") Long[] ids) {
        LambdaQueryWrapper<dish> queryWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<dishFlavor> flavorLambdaQueryWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<setMealDish> mealDishLambdaQueryWrapper = new LambdaQueryWrapper<>();
        mealDishLambdaQueryWrapper.in(ids != null, setMealDish::getDishId, ids);
        queryWrapper.in(ids != null, dish::getId, ids);
        flavorLambdaQueryWrapper.in(ids != null, dishFlavor::getDishId, ids);
        dish DeleteDish = new dish();
        dishFlavor dishFlavor = new dishFlavor();
        DeleteDish.setIsDeleted(1);
        List<dish> list = dishService.list(queryWrapper);
        boolean flag1 = dishService.update(DeleteDish, queryWrapper);
        boolean remove1 = dishService.remove(queryWrapper);
        boolean flag2 = dishFlavorService.update(dishFlavor, flavorLambdaQueryWrapper);
        boolean remove2 = dishFlavorService.remove(flavorLambdaQueryWrapper);
        //操作相应菜品在套餐中的状态
        setMealDish setMealDish = new setMealDish();
        setMealDish.setIsDeleted(1);
        setMealDishService.update(setMealDish, mealDishLambdaQueryWrapper);
        if (remove1 && remove2) {
            //清除redis相应菜品的缓存
            Set<String> removeKeys = new HashSet<>();
            list.forEach(t -> {
                removeKeys.add("dish:" + t.getCategoryId());
            });
            redisTemplate.delete(removeKeys);
            return R.success("删除成功!");
        }
        return R.error("删除失败!");
    }

    /**
     * @param status
     * @param ids
     * @return com.reggie.common.R<java.lang.String>
     * @description: 修改菜品的状态, 停售或起售
     * @author 86187
     * @date: 2022/11/18 15:35
     */

    @PostMapping("/status/{status}")
    public R<String> updateStatus(@PathVariable("status") Integer status, @RequestParam("ids") Long[] ids) {
        log.info("{}:等菜品的状态修改为:{}", ids, status);
        LambdaQueryWrapper<dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ids != null, dish::getId, ids);
        dish updateDish = new dish();
        updateDish.setStatus(status);
        boolean update = dishService.update(updateDish, queryWrapper);
        if (update) {
            //清除redis相应菜品的缓存
            List<dish> list = dishService.list(queryWrapper);
            //利用HashSet集合键名无重复,实现对菜品分类id的去重
            Set<String> removeKeys = new HashSet<>();
            list.forEach(t -> {
                removeKeys.add("dish:" + t.getCategoryId());
            });
            redisTemplate.delete(removeKeys);
            return R.success("修改状态成功!");
        }
        return R.error("修改状态失败!请稍后再试!");
    }


    /**
     * @param id
     * @return com.reggie.common.R<com.reggie.dto.DishDto>
     * @description: 回显指定修改的菜品信息
     * @author 86187
     * @date: 2022/11/19 15:12
     */

    @GetMapping("{id}")
    public R<DishDto> getDishForUpdate(@PathVariable("id") Long id) {
        LambdaQueryWrapper<dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(id != null, dish::getId, id);
        dish updateDish = dishService.getOne(queryWrapper);
        LambdaQueryWrapper<dishFlavor> dishFlavorWrapper = new LambdaQueryWrapper<>();
        dishFlavorWrapper.eq(id != null, dishFlavor::getDishId, id);
        LambdaQueryWrapper<category> categoryWrapper = new LambdaQueryWrapper<>();
        categoryWrapper.eq(id != null, category::getId, updateDish.getCategoryId());
        category category = categoryService.getOne(categoryWrapper);
        List<dishFlavor> FlavorList = dishFlavorService.list(dishFlavorWrapper);//获取对应菜品口味
        //创建dishDto
        DishDto dishDto = new DishDto();
        //将dish的值拷贝到dishDto
        BeanUtils.copyProperties(updateDish, dishDto);
        dishDto.setFlavors(FlavorList);
        dishDto.setCategoryName(category.getName());
        return R.success(dishDto);
    }

    /**
     * @param dishDto
     * @param session
     * @return com.reggie.common.R<java.lang.String>
     * @description: 保存修改后的菜品信息
     * @author 86187
     * @date: 2022/11/19 16:00
     */

    @PutMapping
    public R<String> updateDishDto(@RequestBody DishDto dishDto, HttpSession session) {
        LambdaQueryWrapper<dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(dishDto.getId() != null, dish::getId, dishDto.getId());
        LambdaQueryWrapper<dishFlavor> flavorLambdaQueryWrapper = new LambdaQueryWrapper<>();
        flavorLambdaQueryWrapper.eq(dishDto.getId() != null, dishFlavor::getDishId, dishDto.getId());
        dish dish = new dish();
        dish.setName(dishDto.getName());
        dish.setImage(dishDto.getImage());
        dish.setStatus(dishDto.getStatus());
        dish.setCode(dishDto.getCode());
        dish.setPrice(dishDto.getPrice());
        dish.setCategoryId(dishDto.getCategoryId());
        dish.setDescription(dishDto.getDescription());
        //System.out.println(dishDto.toString());
        boolean dishFlag = dishService.update(dish, queryWrapper);
        boolean saveBatchFlag = true;
        boolean removeFlag = true;
        if (dishDto.getFlavors().size() != 0) {
            saveBatchFlag = dishFlavorService.saveBatch(dishDto.getFlavors());
            //删除之前的信息，保存新的信息
            removeFlag = dishFlavorService.remove(flavorLambdaQueryWrapper);
        }
        log.info("{}:修改了菜品", session.getAttribute("employee"));
        if (dishFlag && saveBatchFlag) {
            //修改成功后去除redis菜品的缓存
            redisTemplate.delete("dish:" + dishDto.getCategoryId());
            return R.success("修改菜品成功!");
        }
        return R.error("修改菜品失败!");
    }

    /**
     * @param id
     * @return com.reggie.common.R<java.util.List < com.reggie.entity.dish>>
     * @description: 返回指定菜品类型的所有菜品, 根据名称返回菜品
     * @author 86187
     * @date: 2022/11/19 16:03
     */

    @GetMapping("/list")
    public R<List<DishDto>> queryDishByCondition(@RequestParam(value = "categoryId", required = false) Long id, @RequestParam(value = "name", required = false) String name, @RequestParam(value = "status", required = false) Integer status) {
        //对redis是否存在进行缓存判断,可以考虑缓存穿透的情况，对进来的id进行判断，如果为空，则直接存入一个对应的null值，
        List<DishDto> dishCache = (List<DishDto>) redisTemplate.opsForValue().get("dish:" + id);
        if (dishCache != null) {
            return R.success(dishCache);
        }
        LambdaQueryWrapper<dish> queryWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<dishFlavor> flavorLambdaQueryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(id != null, dish::getCategoryId, id);
        queryWrapper.like(name != null, dish::getName, name);
        queryWrapper.eq(status != null, dish::getStatus, status);
        List<dish> dishList = dishService.list(queryWrapper);
        List<DishDto> dishDtoList = new ArrayList<>();
        //进行遍历循环赋值
        dishList.forEach(t -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(t, dishDto);
            List<dishFlavor> list = dishFlavorService.list(flavorLambdaQueryWrapper.eq(t.getId() != null, dishFlavor::getDishId, t.getId()));
            dishDto.setFlavors(list);
            dishDtoList.add(dishDto);
        });
        //将数据存进redis中,采用默认的jdk序列化器，采用二进制形式存储数据
        redisTemplate.opsForValue().set("dish:" + id, dishDtoList, 60, TimeUnit.MINUTES);
        return R.success(dishDtoList);
    }
}
